[POWERPC][XEN] Implement guest_physmap_max_mem_pages().
authorHollis Blanchard <hollisb@us.ibm.com>
Fri, 2 Mar 2007 23:07:01 +0000 (17:07 -0600)
committerHollis Blanchard <hollisb@us.ibm.com>
Fri, 2 Mar 2007 23:07:01 +0000 (17:07 -0600)
- Create a p2m array large enough to cover d->max_pages.
- Free in domain_relinquish_resources().
Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
--HG--
extra : transplant_source : %947%3Dm%FB%25%F3%B1%25%AC%05P%DFOE%D2%25%F9%E3%88

xen/arch/powerpc/domain.c
xen/arch/powerpc/mm.c
xen/include/asm-powerpc/domain.h
xen/include/asm-powerpc/mm.h
xen/include/asm-powerpc/shadow.h

index d72d33e202ad0ecabc0529f5347b73a428d049f0..92fa14113ee28b61ed787d4e9416c73b04aa291d 100644 (file)
@@ -16,6 +16,8 @@
  * Copyright IBM Corp. 2005, 2006, 2007
  *
  * Authors: Jimi Xenidis <jimix@watson.ibm.com>
+ *          Ryan Harper <ryanh@us.ibm.com>
+ *          Hollis Blanchard <hollisb@us.ibm.com>
  */
 
 #include <stdarg.h>
@@ -311,6 +313,7 @@ void domain_relinquish_resources(struct domain *d)
     relinquish_memory(d, &d->page_list);
     free_extents(d);
     xfree(d->arch.foreign_mfns);
+    xfree(d->arch.p2m);
     return;
 }
 
index 2a8686c8908032bf40eede73c0ea55671164ab2a..6e972d08e58deeb054e4bc4d9fa7612d54efad9d 100644 (file)
@@ -536,6 +536,47 @@ unsigned long mfn_to_gmfn(struct domain *d, unsigned long mfn)
     return INVALID_M2P_ENTRY;
 }
 
+/* NB: caller holds d->page_alloc lock, sets d->max_pages = new_max */
+int guest_physmap_max_mem_pages(struct domain *d, unsigned long new_max_pages)
+{
+    u32 *p2m_array = NULL;
+    u32 *p2m_old = NULL;
+    ulong i;
+
+    /* XXX We probably could, but right now we don't shrink the p2m array.
+     * NB: d->max_pages >= d->arch.p2m_entries */
+    if (new_max_pages < d->max_pages) {
+        printk("Can't shrink DOM%d max memory pages\n", d->domain_id);
+        return -EINVAL;
+    }
+
+    /* Allocate one u32 per page. */
+    p2m_array = xmalloc_array(u32, new_max_pages);
+    if (p2m_array == NULL)
+        return -ENOMEM;
+
+    /* Copy old mappings into new array. */
+    if (d->arch.p2m != NULL) {
+        /* XXX This could take a long time; we should use a continuation. */
+        memcpy(p2m_array, d->arch.p2m, d->arch.p2m_entries * sizeof(u32));
+        p2m_old = d->arch.p2m;
+    }
+
+    /* Mark new mfns as invalid. */
+    for (i = d->arch.p2m_entries; i < new_max_pages; i++)
+        p2m_array[i] = INVALID_MFN;
+
+    /* Set new p2m pointer and size. */
+    d->arch.p2m = p2m_array;
+    d->arch.p2m_entries = new_max_pages;
+
+    /* Free old p2m array if present. */
+    if (p2m_old)
+        xfree(p2m_old);
+
+    return 0;
+}
+
 void guest_physmap_add_page(
     struct domain *d, unsigned long gpfn, unsigned long mfn)
 {
index b3a10f220cb49b0b6a6fd764c9cbf969fbb4bf8e..c4c0d00a37d93a0dc7335ce2336603c4d408691f 100644 (file)
@@ -13,7 +13,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  *
- * Copyright (C) IBM Corp. 2005
+ * Copyright IBM Corp. 2005, 2007
  *
  * Authors: Hollis Blanchard <hollisb@us.ibm.com>
  */
@@ -47,6 +47,9 @@ struct arch_domain {
     /* I/O-port access bitmap mask. */
     u8 *iobmp_mask;       /* Address of IO bitmap mask, or NULL.      */
 
+    u32 *p2m; /* Array of 32-bit MFNs supports 44 bits of physical memory. */
+    ulong p2m_entries;
+
     uint large_page_sizes;
     uint large_page_order[4];
 } __cacheline_aligned;
index dd35d8887a8c3c0006fa0cd49d66391422651e62..e89d21036926fb1f92426b27d1ef0b68af8c44f6 100644 (file)
@@ -239,7 +239,9 @@ extern unsigned long mfn_to_gmfn(struct domain *d, unsigned long mfn);
 
 extern unsigned long paddr_to_maddr(unsigned long paddr);
 
-#define INVALID_MFN (~0UL)
+/* INVALID_MFN can be any value that fails mfn_valid(). */
+#define INVALID_MFN (~0U)
+
 #define PFN_TYPE_NONE 0
 #define PFN_TYPE_RMA 1
 #define PFN_TYPE_LOGICAL 2
index f9703270ab1f89e49609b0630270346c073963fb..479133b4b86783a172dbc4f673e934d5af21bfbb 100644 (file)
@@ -32,6 +32,8 @@
       ? machine_to_phys_mapping[(mfn)]                 \
       : (mfn) )
 
+extern int guest_physmap_max_mem_pages(struct domain *d, unsigned long new_max);
+
 extern void guest_physmap_add_page(
     struct domain *d, unsigned long gpfn, unsigned long mfn);
 
@@ -60,7 +62,5 @@ static inline unsigned int shadow_get_allocation(struct domain *d)
     return (1ULL << (d->arch.htab.order + PAGE_SHIFT)) >> 20;
 }
 
-#define guest_physmap_max_mem_pages(d, n) (0)
-
 #endif